//------------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
//            (C) COPYRIGHT 2012-2013 ARM Limited.
//                ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//------------------------------------------------------------------------------
// Version and Release Control Information:
//
// File Revision       : 149905
// File Date           :  2013-05-08 18:27:40 +0100 (Wed, 08 May 2013)
// Release Information : PL401-r0p1-00eac0
//------------------------------------------------------------------------------
// Verilog-2001 (IEEE Std 1364-2001)
//------------------------------------------------------------------------------
// Purpose : HDL design file for AMBA master interface block
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
//                               nic400_amib_sys_gp_apb4_ysyx_rv32.v
//                               =============
//
//------------------------------------------------------------------------------
//
//  Overview
// ==========
//
//   The Axi Master Interface Block provides an interface between an interconnect
// and an external slave port on NIC400.
//
//   The AMIB can be configured to provide four modes of operation for each of
// the channels:
//    1. fully registered (total timing isolation between
//                         master and slave ports)
//    2. forward path registered only (timing isolation on data/ctrl/valid
//                                     paths only)
//    3. reverse path registered only (timing isolation on ready paths only)
//
//------------------------------------------------------------------------------


`include "nic400_amib_sys_gp_apb4_defs_ysyx_rv32.v"

module nic400_amib_sys_gp_apb4_ysyx_rv32
  (
  
    //APB Bus
    paddr_clint_slv_apb4,
    pwdata_clint_slv_apb4,
    pwrite_clint_slv_apb4,
    pprot_clint_slv_apb4,
    pstrb_clint_slv_apb4,
    penable_clint_slv_apb4,
    psel_clint_slv_apb4,
    prdata_clint_slv_apb4,
    pslverr_clint_slv_apb4,
    pready_clint_slv_apb4,

    //APB Bus
    paddr_plic_slv_apb4,
    pwdata_plic_slv_apb4,
    pwrite_plic_slv_apb4,
    pprot_plic_slv_apb4,
    pstrb_plic_slv_apb4,
    penable_plic_slv_apb4,
    psel_plic_slv_apb4,
    prdata_plic_slv_apb4,
    pslverr_plic_slv_apb4,
    pready_plic_slv_apb4,

    //APB Bus
    paddr_rcu_slv_apb4,
    pwdata_rcu_slv_apb4,
    pwrite_rcu_slv_apb4,
    pprot_rcu_slv_apb4,
    pstrb_rcu_slv_apb4,
    penable_rcu_slv_apb4,
    psel_rcu_slv_apb4,
    prdata_rcu_slv_apb4,
    pslverr_rcu_slv_apb4,
    pready_rcu_slv_apb4,

    //sys_gp_apb4_s ITB bus

    //A Channel
    aid_sys_gp_apb4_s,
    aaddr_sys_gp_apb4_s,
    alen_sys_gp_apb4_s,
    asize_sys_gp_apb4_s,
    aburst_sys_gp_apb4_s,
    alock_sys_gp_apb4_s,
    acache_sys_gp_apb4_s,
    aprot_sys_gp_apb4_s,
    awrite_sys_gp_apb4_s,
    avalid_sys_gp_apb4_s,
    aregion_sys_gp_apb4_s,
    aready_sys_gp_apb4_s,

    //W Channel
    wdata_sys_gp_apb4_s,
    wstrb_sys_gp_apb4_s,
    wlast_sys_gp_apb4_s,
    wvalid_sys_gp_apb4_s,
    wready_sys_gp_apb4_s,

    //D Channel
    did_sys_gp_apb4_s,
    ddata_sys_gp_apb4_s,
    dresp_sys_gp_apb4_s,
    dlast_sys_gp_apb4_s,
    dbnr_sys_gp_apb4_s,
    dvalid_sys_gp_apb4_s,
    dready_sys_gp_apb4_s,

    //Clock and reset signals
    apb_pclken,
    aclk,
    aresetn

  );




  // ---------------------------------------------------------------------------
  //  Port definitions
  // ---------------------------------------------------------------------------
  
  //APB Bus
  output  [31:0]      paddr_clint_slv_apb4;  
  output  [31:0]      pwdata_clint_slv_apb4; 
  output              pwrite_clint_slv_apb4; 
  output  [2:0]       pprot_clint_slv_apb4;  
  output  [3:0]       pstrb_clint_slv_apb4;  
  output              penable_clint_slv_apb4;
  output              psel_clint_slv_apb4;   
  input   [31:0]      prdata_clint_slv_apb4; 
  input               pslverr_clint_slv_apb4;
  input               pready_clint_slv_apb4; 

  //APB Bus
  output  [31:0]      paddr_plic_slv_apb4;   
  output  [31:0]      pwdata_plic_slv_apb4;  
  output              pwrite_plic_slv_apb4;  
  output  [2:0]       pprot_plic_slv_apb4;   
  output  [3:0]       pstrb_plic_slv_apb4;   
  output              penable_plic_slv_apb4; 
  output              psel_plic_slv_apb4;    
  input   [31:0]      prdata_plic_slv_apb4;  
  input               pslverr_plic_slv_apb4; 
  input               pready_plic_slv_apb4;  

  //APB Bus
  output  [31:0]      paddr_rcu_slv_apb4;    
  output  [31:0]      pwdata_rcu_slv_apb4;   
  output              pwrite_rcu_slv_apb4;   
  output  [2:0]       pprot_rcu_slv_apb4;    
  output  [3:0]       pstrb_rcu_slv_apb4;    
  output              penable_rcu_slv_apb4;  
  output              psel_rcu_slv_apb4;     
  input   [31:0]      prdata_rcu_slv_apb4;   
  input               pslverr_rcu_slv_apb4;  
  input               pready_rcu_slv_apb4;   

  //sys_gp_apb4_s ITB bus


  //A Channel
  input   [3:0]       aid_sys_gp_apb4_s;           //id of sys_gp_apb4_s bus
  input   [31:0]      aaddr_sys_gp_apb4_s;         //address of sys_gp_apb4_s bus
  input   [7:0]       alen_sys_gp_apb4_s;          //length field of sys_gp_apb4_s bus
  input   [2:0]       asize_sys_gp_apb4_s;         //size of sys_gp_apb4_s bus
  input   [1:0]       aburst_sys_gp_apb4_s;        //burst length of sys_gp_apb4_s bus
  input               alock_sys_gp_apb4_s;         //lock of sys_gp_apb4_s bus
  input   [3:0]       acache_sys_gp_apb4_s;        //cache field of sys_gp_apb4_s bus
  input   [2:0]       aprot_sys_gp_apb4_s;         //prot field of sys_gp_apb4_s bus
  input               awrite_sys_gp_apb4_s;        //direction of sys_gp_apb4_s bus
  input               avalid_sys_gp_apb4_s;        //valid of sys_gp_apb4_s bus
  input   [3:0]       aregion_sys_gp_apb4_s;       //region selection signal of sys_gp_apb4_s bus
  output              aready_sys_gp_apb4_s;        //ready of sys_gp_apb4_s bus

  //W Channel
  input   [31:0]      wdata_sys_gp_apb4_s;         //write data of sys_gp_apb4_s AXI bus W Channel
  input   [3:0]       wstrb_sys_gp_apb4_s;         //write strobes of sys_gp_apb4_s AXI bus W Channel
  input               wlast_sys_gp_apb4_s;         //write last of sys_gp_apb4_s AXI bus W Channel
  input               wvalid_sys_gp_apb4_s;        //write valid of sys_gp_apb4_s AXI bus W Channel
  output              wready_sys_gp_apb4_s;        //write ready of sys_gp_apb4_s AXI bus W Channel

  //D Channel
  output  [3:0]       did_sys_gp_apb4_s;           //id of sys_gp_apb4_s bus
  output  [31:0]      ddata_sys_gp_apb4_s;         //data of sys_gp_apb4_s bus
  output  [1:0]       dresp_sys_gp_apb4_s;         //response status of sys_gp_apb4_s bus
  output              dlast_sys_gp_apb4_s;         //last of sys_gp_apb4_s bus
  output              dbnr_sys_gp_apb4_s;          //response type of sys_gp_apb4_s bus
  output              dvalid_sys_gp_apb4_s;        //valid of sys_gp_apb4_s bus
  input               dready_sys_gp_apb4_s;        //ready of sys_gp_apb4_s bus

  //Clock and reset signals
  input               apb_pclken;                  //apb master port clock enable
  input               aclk;                        //main clock
  input               aresetn;                     //main reset



  //----------------------------------------------------------------------------
  // Internal wires
  //----------------------------------------------------------------------------



  wire           w_master_port_dst_valid;
  wire           w_master_port_dst_ready;
  wire           w_master_port_src_valid;
  wire           w_master_port_src_ready;

  wire [36:0]    w_master_port_src_data;     // concatenation of the inputs
  wire [36:0]    w_master_port_dst_data;     // concatenation of the registered inputs


  // W Channel
  wire [31:0]    wdata_apb;
  wire [3:0]     wstrb_apb;
  wire           wlast_apb;
  wire           wvalid_apb;
  wire           wready_apb;



  //----------------------------------------------------------------------------
  // Internal APB wires
  //----------------------------------------------------------------------------
  wire                            penable_apb;          // Common APB PENABLE
  wire                            pwrite_apb;           // Common APB PWRITE
  wire [31:0]                     paddr_apb;            // Common APB PADDR
  wire [31:0]                     pwdata_apb;           // Common APB PWDATA

  wire [2:0]                      pprot_apb;            // Common APB PPROT
  wire [3:0]                      pstrb_apb;            // Common APB PSTRB

  // ---------------------------------------------------------------------------


  // ---------------------------------------------------------------------------
  //  start of code
  // ---------------------------------------------------------------------------


  // ---------------------------------------------------------------------------
  // W Channel timing block wiring at Master Port
  // ---------------------------------------------------------------------------

  // the inputs are concatenated to interface to the generic register set
  assign w_master_port_src_data = {wdata_sys_gp_apb4_s,
        wstrb_sys_gp_apb4_s,
        wlast_sys_gp_apb4_s};

  // expand the concatenated registered values to the master port outputs
  assign {wdata_apb,
        wstrb_apb,
        wlast_apb} = w_master_port_dst_data;

  assign wvalid_apb = w_master_port_dst_valid;
  assign w_master_port_dst_ready = wready_apb;

  assign w_master_port_src_valid = wvalid_sys_gp_apb4_s;
  assign wready_sys_gp_apb4_s = w_master_port_src_ready;


  //----------------------------------------------------------------------------
  // APB Protocol conversion
  //----------------------------------------------------------------------------
  nic400_amib_sys_gp_apb4_apb_m_ysyx_rv32 #(
    .ID_WIDTH         (4),
    .ADDR_WIDTH       (32)
  ) u_apb_m
  (
    .aclk             (aclk),
    .aresetn          (aresetn),

    .awrite           (awrite_sys_gp_apb4_s),
    .aid              (aid_sys_gp_apb4_s),
    .aaddr            (aaddr_sys_gp_apb4_s),
    .alen             (alen_sys_gp_apb4_s),
    .asize            (asize_sys_gp_apb4_s),
    .aburst           (aburst_sys_gp_apb4_s),
    .aregion          (aregion_sys_gp_apb4_s),
    .aprot            (aprot_sys_gp_apb4_s),

    .avalid           (avalid_sys_gp_apb4_s),
    .aready           (aready_sys_gp_apb4_s),

    .dbnr             (dbnr_sys_gp_apb4_s),
    .did              (did_sys_gp_apb4_s),
    .ddata            (ddata_sys_gp_apb4_s),
    .dresp            (dresp_sys_gp_apb4_s),
    .dlast            (dlast_sys_gp_apb4_s),
    .dvalid           (dvalid_sys_gp_apb4_s),
    .dready           (dready_sys_gp_apb4_s),

    .wdata            (wdata_apb),
    .wstrb            (wstrb_apb),
    .wlast            (wlast_apb),
    .wvalid           (wvalid_apb),
    .wready           (wready_apb),

    .pclken           (apb_pclken),
    .psel_clint_slv_apb4_i     (psel_clint_slv_apb4),
    .psel_plic_slv_apb4_i     (psel_plic_slv_apb4),
    .psel_rcu_slv_apb4_i     (psel_rcu_slv_apb4),
    .pready_clint_slv_apb4_i   (pready_clint_slv_apb4),
    .pready_plic_slv_apb4_i   (pready_plic_slv_apb4),
    .pready_rcu_slv_apb4_i   (pready_rcu_slv_apb4),
    .pslverr_clint_slv_apb4_i  (pslverr_clint_slv_apb4),
    .pslverr_plic_slv_apb4_i  (pslverr_plic_slv_apb4),
    .pslverr_rcu_slv_apb4_i  (pslverr_rcu_slv_apb4),
    .prdata_clint_slv_apb4_i   (prdata_clint_slv_apb4),
    .prdata_plic_slv_apb4_i   (prdata_plic_slv_apb4),
    .prdata_rcu_slv_apb4_i   (prdata_rcu_slv_apb4),
    .penable          (penable_apb),
    .pwrite           (pwrite_apb),
    .paddr            (paddr_apb),
    .pwdata           (pwdata_apb),
    .pprot            (pprot_apb),
    .pstrb            (pstrb_apb)

  );


  assign penable_clint_slv_apb4 = penable_apb;
  assign penable_plic_slv_apb4 = penable_apb;
  assign penable_rcu_slv_apb4 = penable_apb;

  assign pwrite_clint_slv_apb4 = pwrite_apb;
  assign pwrite_plic_slv_apb4 = pwrite_apb;
  assign pwrite_rcu_slv_apb4 = pwrite_apb;

  assign paddr_clint_slv_apb4 = paddr_apb;
  assign paddr_plic_slv_apb4 = paddr_apb;
  assign paddr_rcu_slv_apb4 = paddr_apb;

  assign pwdata_clint_slv_apb4 = pwdata_apb;
  assign pwdata_plic_slv_apb4 = pwdata_apb;
  assign pwdata_rcu_slv_apb4 = pwdata_apb;

  assign pprot_clint_slv_apb4 = pprot_apb;
  assign pprot_plic_slv_apb4 = pprot_apb;
  assign pprot_rcu_slv_apb4 = pprot_apb;

  assign pstrb_clint_slv_apb4 = pstrb_apb;
  assign pstrb_plic_slv_apb4 = pstrb_apb;
  assign pstrb_rcu_slv_apb4 = pstrb_apb;



  // ---------------------------------------------------------------------------
  // Instantiation of Timing Isolation Blocks
  // ---------------------------------------------------------------------------

  //  W Channel Timing Isolation Register Block on master_port

  // HNDSHK_MODE = rev
  // PAYLOAD_WIDTH = 37
  nic400_amib_sys_gp_apb4_chan_slice_ysyx_rv32
    #(
       `RS_REV_REG,  // Handshake Mode
       37  // Payload Width
     )
  u_w_master_port_chan_slice
    (
     // global interconnect inputs
     .aresetn               (aresetn),
     .aclk                  (aclk),
     // inputs
     .src_valid             (w_master_port_src_valid),
     .src_data              (w_master_port_src_data),
     .dst_ready             (w_master_port_dst_ready),

     // outputs
     .src_ready             (w_master_port_src_ready),
     .dst_data              (w_master_port_dst_data),
     .dst_valid             (w_master_port_dst_valid)
     );



  // A channel is set to wires at master_port.

  // D channel is set to wires at master_port.

  // AW channel is set to wires at slave_port.

  // AR channel is set to wires at slave_port.

  // R channel is set to wires at slave_port.

  // W channel is set to wires at slave_port.

  // B channel is set to wires at slave_port.


//==============================================================================
// OVL Assertions
//==============================================================================
`ifdef ARM_ASSERT_ON

// Include Standard OVL Defines
`include "std_ovl_defines.h"

  //----------------------------------------------------------------------------
  // OVL_ASSERT: Lock Transaction received when not supported.
  //----------------------------------------------------------------------------
  //
  //----------------------------------------------------------------------------
  // OVL_ASSERT_RTL

  wire lock_rx_no_lock_support;

  // Signals that a locking transaction has been received when not supported.
  assign lock_rx_no_lock_support = 1'b0;


  assert_never #(`OVL_ERROR,
                 `OVL_ASSERT,
                 "AMIB: Lock transaction received when not supported.")
  amib_lock_no_lock_support
  (
    .clk        (aclk),
    .reset_n    (aresetn),
    .test_expr  (lock_rx_no_lock_support)
  );
  // OVL_ASSERT_END


  `endif // ARM_ASSERT_ON

endmodule

`include "nic400_amib_sys_gp_apb4_undefs_ysyx_rv32.v"

// --================================= End ===================================--
